using IQIGame.Onigao.Framework;
using NetProtocol.POD;

namespace IQIGame.Onigao.Logic
{
    public abstract class BaseLevelBuff : BaseLevelEO
    {
        public abstract int cid { get; }
        public bool isExpired { get; set; }
        public int stack { get; protected set; }
        public abstract int durationFrame { get; }
        public abstract int triggerInterval { get; }
        public abstract int maxStack { get; }
        public int leftFrame
        {
            get
            {
                if (durationFrame <= 0)
                    return -1;
                int f = durationFrame - (_host.region.level.levelFrame - _startFrame);
                if (f < 0)
                {
                    f = 0;
                }
                return f;
            }
        }
        protected BaseLevelFunctionHost _host;
        protected int _startFrame;


        public void LogicOnUpdate()
        {
            if (isExpired)
                return;
            OnUpdateIntervalTrigger();
            if (durationFrame > 0 && _host.region.level.levelFrame - _startFrame >= durationFrame)
            {
                isExpired = true;
            }
        }

        protected virtual void OnUpdateIntervalTrigger()
        {

        }

        public virtual void OnAdd()
        {
            _startFrame = _host.region.level.levelFrame;
            stack = 1;
        }

        public virtual void OnRemove()
        {

        }

        /// <summary>
        /// 当添加堆叠时处理的逻辑
        /// </summary>
        /// <param name="addValue"></param>
        /// <param name="isManualModify">是否通过执行手动修改，如果不是，则是通过同id buff叠加和驱散机制自动修改</param>
        protected virtual void OnAddStack(int addValue, bool isManualModify)
        {

        }

        /// <summary>
        /// 增加堆叠层数
        /// </summary>
        /// <param name="addValue"></param>
        /// <param name="isManualModify">是否通过执行手动修改，如果不是，则是通过同id buff叠加和驱散机制自动修改</param>
        /// <returns></returns>
        public virtual bool AddStack(int addValue, bool isManualModify)
        {
            if (isExpired)
            {
                return false;
            }
            int oldStack = stack;
            stack += addValue;
            if (stack < 0)
            {
                stack = 0;
            }
            else
            {
                var maxStack = this.maxStack;
                if (maxStack > 0 && stack > maxStack)
                {
                    stack = maxStack;
                }
            }
            OnAddStack(addValue, isManualModify);
            return addValue > 0 || oldStack != stack;
        }

        public abstract bool TryTriggerService(ServiceTriggerType triggerType = ServiceTriggerType.None);

        public override IPOD GeneratePOD()
        {
            LevelBuffPOD pod = new LevelBuffPOD();
            pod.cid = cid;
            pod.stack = stack;
            pod.leftSec = leftFrame == -1 ? -1 : (float)leftFrame / LgLevelConst.FrameRate;
            return pod;
        }

        public string GetDebugInfo()
        {
#if UNITY_EDITOR
            string hostType = "UnKnown";
            string idLabel = "id";
            string id = "0";
            if (_host is LevelPlayer)
            {
                hostType = "Player";
                id = (_host as LevelPlayer).id.ToString();
            }
            else if (_host is LevelHero)
            {
                hostType = "Hero";
                id = (_host as LevelHero).id.ToString();
            }
            else if (_host is LevelEntity)
            {
                hostType = "Entity";
                idLabel = "tags";
                id = $"[ {string.Join(", ", (_host as LevelEntity).tags)} ]";
            }
            return $"挂载对象类型：{hostType}，对象{idLabel}：{id}，buff cid：{cid}，层数：{stack}，剩余时间：{(leftFrame == -1 ? "永久" : (float)leftFrame * 1000 / LgLevelConst.FrameRate + "毫秒")}";
#else
            return string.Empty;
#endif
        }

        public override void OnReset()
        {
            base.OnReset();
            _host = null;
            _startFrame = 0;
            isExpired = false;
            stack = 0;
        }
    }
}
